package com.bluedemokk.www.blue;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import java.util.List;
import java.util.UUID;

public class BlueAdapter {
    private static final UUID UUID_WRITE_SERVICE        = UUID.fromString("00001000-0000-1000-8000-00805f9b34fb");
    private static final UUID UUID_WRITE                = UUID.fromString("00001001-0000-1000-8000-00805f9b34fb");
    private Context                     mContext;
    private BluetoothManager            bluetoothManager;
    private BluetoothAdapter            bluetoothAdapter;
    private BluetoothGatt               bluetoothGatt;
    private BluetoothGattCharacteristic writeCharacteristic;

    private BluetoothDevice       usedDevice;
    private String needConnDeviceName;

    private boolean isConnected = false;

    //============================================
    /**
     * 加入蓝牙事件接收器
     */
    public static int current_blue_state = 0;
    private OnBlueStateListener onBlueStateListener;
    public void setOnBlueStateListener(OnBlueStateListener listener) {
        this.onBlueStateListener = listener;
    }
    //============================================
    private static BlueAdapter _instance;
    protected BlueAdapter() {
    }
    public static BlueAdapter getInstance() {
        if (_instance == null)
            _instance = new BlueAdapter();
        return _instance;
    }
    //====================启动过程========================
    public void init(Context context) {
        this.mContext = context;
        if (bluetoothManager == null)
            bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        if (bluetoothAdapter == null) {
            bluetoothAdapter = bluetoothManager.getAdapter();
        }
    }
    //=======================扫描过程=====================
    private long startScanTime = 0;
    @SuppressLint("NewApi")
    private void gotoDiscoverDevice() {
        if (bluetoothAdapter.isDiscovering()) return;
        initScanCallback();
        startScanTime = System.currentTimeMillis();
        boolean isScan = bluetoothAdapter.startLeScan(mLeScanCallback);//去扫描匹配,开始搜索
        Log.i(">>>Blue>>>", "---开始了新搜索---isScan:"+isScan);
    }
    @SuppressLint("NewApi")
    public void stopScaning() {//停扫描
        if (mLeScanCallback != null && bluetoothAdapter != null)
            Toast.makeText(mContext, "停止扫描", Toast.LENGTH_SHORT).show();
            bluetoothAdapter.stopLeScan(mLeScanCallback);
    }
    private BluetoothAdapter.LeScanCallback mLeScanCallback;
    @SuppressLint("NewApi")
    private void initScanCallback() {
        if (mLeScanCallback == null) mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                long now = System.currentTimeMillis();
                if (now - startScanTime > 10000) {//10秒搜不到
                    stopScaning();
                    Toast.makeText(mContext, "扫描不到结果...", Toast.LENGTH_SHORT).show();
                }
                if(device == null || device.getAddress() == null || device.getName()==null)return;
                Log.i(">>>Blue>>>", "---正在扫描...---搜索到:"+device.getName());
                if(device.getName().equals(needConnDeviceName)){
                    Toast.makeText(mContext, "扫描名称："+device.getName()+"  输入名称："+needConnDeviceName, Toast.LENGTH_SHORT).show();
                    usedDevice = device;
                    stopScaning();
                    bluetoothGatt = usedDevice.connectGatt(mContext, true, mGattCallback);

                    Toast.makeText(mContext, "正在链接"+bluetoothGatt, Toast.LENGTH_SHORT).show();
                }
            }
        };
    }
    @SuppressLint("NewApi")
    public void needConnectDevice(String deviceName) {
        needConnDeviceName = deviceName;
        if (isConnected && usedDevice != null && needConnDeviceName.equals(usedDevice.getName())) {
            Toast.makeText(mContext, "已经链接了", Toast.LENGTH_SHORT).show();
            return;//是已经连上的
        }else
            gotoDiscoverDevice();
    }
    //==========================启动扫描==========================

    @SuppressLint("NewApi")
    private final BluetoothGattCallback mGattCallback   = new BluetoothGattCallback() {
        @Override  //当连接上设备或者失去连接时会回调该函数
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            Toast.makeText(mContext, "gatt:。。。  "+gatt, Toast.LENGTH_SHORT).show();
            if (gatt == null) return;
            if (newState == BluetoothProfile.STATE_CONNECTED) { //连接成功
                isConnected = true;
                Toast.makeText(mContext, "链接成功...", Toast.LENGTH_SHORT).show();
                if (bluetoothGatt != null) bluetoothGatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {  //连接失败
                Toast.makeText(mContext, "链接失败...", Toast.LENGTH_SHORT).show();
                Log.e(">>>Blue>>>", "--------STATE_DISCONNECTED && onConnectedFailed-----");
                if (writeCharacteristic != null) writeCharacteristic = null;
                isConnected = false;
                if (bluetoothGatt != null) bluetoothGatt.close();//每次重连
                bluetoothGatt = null;
                usedDevice = null;
                if (onBlueStateListener != null) onBlueStateListener.onConnectedFailed("蓝牙断开连接");
            }
        }

        @Override  //当设备是否找到服务时，会回调该函数
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {   //找到服务了
                //在这里可以对服务进行解析，寻找到你需要的服务
                Log.e(">>>Blue>>>", "--------已找到服务列表-----bluetoothGatt != null:"+(gatt != null));
                if (gatt != null) {
                    BluetoothGattService serviceSS = gatt.getService(UUID_WRITE_SERVICE);
                    Toast.makeText(mContext, "服务："+serviceSS, Toast.LENGTH_SHORT).show();
                    if (serviceSS != null){
                        displayGattServices(serviceSS);
                    }
                }
            } else {
                Log.e(">>>Blue>>>", "--------未找到服务列表-----");
                Toast.makeText(mContext, "未找到服务列表", Toast.LENGTH_SHORT).show();
            }
        }


        @Override //通知收到消息
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            byte[] bytes = characteristic.getValue();
            Log.e(">>>Blue>>>", "收到消息成功");
            Toast.makeText(mContext, "收到消息成功", Toast.LENGTH_SHORT).show();
            if (onBlueStateListener != null) onBlueStateListener.onReceiveData(bytes);
        }

        @Override //通知发出消息实体
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            final byte[] result = characteristic.getValue();
            Log.e(">>>Blue>>>", "发出消息成功");
            Toast.makeText(mContext, "发送消息成功", Toast.LENGTH_SHORT).show();
            if (onBlueStateListener != null) onBlueStateListener.onMessageSended(result);
        }

    };
    /**
     * 7.解析所有服务
     */
    @SuppressLint("NewApi")
    private void displayGattServices(BluetoothGattService gattServices) {
        if (gattServices == null) {
            Log.e(">>>Blue>>>", "Service列表无数据");
            Toast.makeText(mContext, "Service列表无数据", Toast.LENGTH_SHORT).show();
            return;
        }
        Log.e(">>>Blue>>>", "--------开始检索服务列表-----");
        writeCharacteristic = null;
        List<BluetoothGattCharacteristic> gattCharacteristics = gattServices.getCharacteristics();
        for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { // 遍历每条服务里的所有Characteristic
            UUID uuid_this = gattCharacteristic.getUuid();
            if (uuid_this.equals(UUID_WRITE)) {
                boolean isEnableNotification = bluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
                if (isEnableNotification) {
                    for (BluetoothGattDescriptor descriptor : gattCharacteristic.getDescriptors()) {
                        if (descriptor != null) {
                            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                        }
                    }
                    writeCharacteristic = gattCharacteristic;
                    if (onBlueStateListener != null) onBlueStateListener.onConnectedOK();
                }
            }
        }
    }

    public void closeBlueConn() {
        if (bluetoothGatt != null && isConnected) {
            bluetoothGatt.disconnect();
        }
    }
    //==================================get=========================================
    @SuppressLint("NewApi")
    public boolean sendMessage(String hexStr) {
        if (isConnected && bluetoothGatt != null && bluetoothGatt.connect() && writeCharacteristic != null) {
            Log.i(">>>Blue>>>", " 发包蓝牙：" + hexStr);
            writeCharacteristic.setValue(HexUtil.hexStringToBytes(hexStr));
            bluetoothGatt.writeCharacteristic(writeCharacteristic);
            return true;
        } else {
            Toast.makeText(mContext, "isConnected：" +isConnected +"  bluetoothGatt:"+bluetoothGatt+"   bluetoothGatt.connect():"+bluetoothGatt.connect()+"  writeCharacteristic:"+writeCharacteristic, Toast.LENGTH_LONG).show();
            return false;
        }
    }
}
